#ifndef _UNIT_STATUS_C0MMON_H_
#define _UNIT_STATUS_C0MMON_H_

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#pragma pack(1)

// 定义枚举类型表示不同的报文编号
typedef enum
{
  MESSAGE_TYPE_1 = 1,
  MESSAGE_TYPE_2,
  MESSAGE_TYPE_3,
  MESSAGE_TYPE_4
} MessageType;
// 定义报文编号1对应的结构体
typedef struct
{
  uint8_t workMode;          // 工作模式，0:手动, 1:自动
  uint8_t overVoltEn;        // 过压保护使能，0:启用, 1:仅报警, 2:禁用
  uint8_t overVoltVal;       // 过压保护阈值，50 - 80
  uint8_t overCurEn;         // 过流保护使能，0:定时限, 1:反时限, 2:仅报警
  uint8_t overCurVal;        // 过流保护阈值
  uint8_t overVoltDelay;     // 过压保护延时时间，1 - 60 (秒)
  uint8_t underVoltEn;       // 欠压保护使能，0:启用, 1:仅报警, 2:禁用
  uint8_t underVoltVal;      // 欠压保护阈值，35 - 49
  uint8_t underVoltDelay;    // 欠压保护延时时间，1 - 60 (秒)
  uint8_t portTempEn;        // 端口温度保护使能，0:启用, 1:仅报警, 2:禁用
  uint8_t portTempVal;       // 端口温度保护阈值，70 - 130
  uint8_t portTempDelay;     // 端口温度保护延时时间，1 - 60
  uint8_t boardTempEn;       // 板载温度保护使能，0:启用, 1:仅报警, 2:禁用
  uint8_t boardTempVal;      // 板载温度保护阈值，70 - 100
  uint8_t boardTempDelay;    // 板载温度保护延时时间，1 - 60
  uint8_t overCurReEn;       // 过流自动重合使能，0:启用, 1:禁用
  uint8_t overCurReDelay;    // 过流自动重合延时时间，1 - 60
  uint8_t overCurReCnt;      // 过流自动重合次数，1 - 5
  char energySettleTime[11]; // 电量结算时间，例：01 10:10
  uint64_t last_send_time;   // 采集时间，例：2024 - 01 - 17 00:11:15
  uint8_t need_updata_flag;
} Message1;

// 定义报文编号2对应的结构体
typedef struct
{
  bool online;             // 在线情况，1:在线, 0:离线
  float vol;               // 输入电压，精度0.01
  float cur;               // 空开电流，精度0.01
  float pow;               // 空开功率，精度0.01
  float curMonthEnergy;    // 当月电量，精度0.01
  float lastMonthEnergy;   // 上月电量，精度0.01
  float T1;                // 端口温度
  float T2;                // 板载温度
  float in_ene;            // 空开输入电量
  float out_ene;           // 空开输出电量
  uint8_t sta;             // 开关状态，0:开闸, 1:关闸
  bool authState;          // 授权状态，0:未授权，1:授权
  uint64_t last_send_time; // 采集时间，例：2024 - 01 - 17 00:11:15
  uint8_t need_updata_flag;
} Message2;

// 定义报文编号3对应的结构体
typedef struct
{
  uint8_t switchState;     // 分闸合闸状态，0:分闸, 1:合闸
  bool authState;          // 授权状态，0:未授权, 1:授权
  uint64_t last_send_time; // 采集时间，例：2024 - 01 - 17 00:11:15
  uint8_t need_updata_flag;
} Message3;

// 定义报文编号4对应的结构体
typedef struct
{
  bool underVoltAlarm;     // 欠压告警
  bool overVoltAlarm;      // 过压告警
  bool overCurAlarm;       // 过流告警
  bool portTempAlarm;      // 端口温度告警
  bool boardTempAlarm;     // 板载温度告警
  bool switchOpenAlarm;    // 空开断开告警
  uint64_t last_send_time; // 采集时间，例：2024 - 01 - 17 00:11:15
  uint8_t need_updata_flag;
} Message4;

// 定义一个结构体，用于存储不同类型的报文
typedef struct
{
  Message1 message1;
  Message2 message2;
  Message3 message3;
  Message4 message4;
  uint8_t rever[16];
} MessageData;
extern MessageData *send_message;
// 1. 通讯参数结构体（对应0x1800~0x1803）
typedef struct
{
  uint8_t dev_addr;   // 设备地址（0x1800高字节，1~247）
  uint32_t baud_rate; // 波特率（0x1800低字节：0=19200,1=9600,2=4800）
  uint8_t parity;     // 校验位（0x1801高字节：0=无,2=偶,4=奇）
  uint8_t stop_bit;   // 停止位（0x1801低字节：0=1位,1=2位）
} Modbus_CommParam;

// 2. 运行状态结构体（对应0x1804~0x18B5，含核心变量，预留寄存器忽略）
typedef struct
{
  // 0x1804~0x180F
  float input_volt_1;         // 输入电压1（0x1804~0x1805，Y*0.01，单位V）
  float air_switch_current_1; // 空开电流1（0x1806~0x1807，Y*0.01，单位A）
  float air_switch_power;     // 空开功率（0x1808~0x1809，Y*0.01，单位kW）
  float output_energy;        // 输出电量（0x180E~0x180F，Y*0.01，单位kWh）

  // 0x1818~0x181B
  int16_t port_temp;        // 端口温度（0x1818，单位℃）
  int16_t board_temp;       // 板载温度（0x1819，单位℃）
  int32_t bus_meter_volt_1; // 母排计量电压1（0x181A~0x181B，单位V×100）

  // 0x1824~0x1828
  uint16_t run_status_word;       // 运行状态字（0x1824，需附录5.2解析）
  uint16_t alarm_word1;           // 报警状态字1（0x1825，需附录5.2解析）
  uint16_t alarm_word2;           // 报警状态字2（0x1826，需附录5.2解析）
  float input_energy_discharge_1; // 输入电量（放电1，0x1827~0x1828，Y*0.01，kWh）

  // 0x18A4~0x18B5
  int32_t input_volt_2;           // 输入电压2（0x18A4~0x18A5，单位V×100）
  int32_t air_switch_current_2;   // 空开电流2（0x18A6~0x18A7，单位A×100）
  float total_energy;             // 累计电量（0x18A8~0x18A9，Y*0.01，kWh）
  float input_energy_discharge_2; // 输入电量（放电2，0x18AA~0x18AB，Y*0.01，kWh）
  float output_energy_2;          // 输出电量2（0x18AC~0x18AD，Y*0.01，kWh）
  uint16_t run_status_word_2;     // 运行状态字2（0x18AE，需附录5.2解析）
  uint16_t alarm_word1_2;         // 报警状态字1_2（0x18AF，需附录5.2解析）
  uint16_t alarm_word2_2;         // 报警状态字2_2（0x18B0，需附录5.2解析）
  uint16_t dev_query;             // 设备查询（0x18B1：0x00AA=快闪20s）
  uint16_t flash_duration;        // 闪灯时长（0x18B2，单位s，默认20）
  uint16_t clear_energy_cmd;      // 清除电量命令（0x18B3：0x00AA=清零）
  int32_t bus_meter_volt_2;       // 母排计量电压2（0x18B4~0x18B5，单位V×100）
} Modbus_RunStatus;

// 3. 装置信息结构体（对应0x1900~0x190E）
typedef struct
{
  uint8_t factory_sn[8];  // 厂家SN（0x1900~0x1903，8字节：厂家代码+年份+月份+序列号）
  float software_version; // 软件版本（0x1904~0x1905，格式XX.XX）
  uint16_t switch_width;  // 开关宽度（0x190C：0x000A=20mm,0x000F=30mm）
  uint8_t rated_volt;     // 额定电压（0x190D高字节，单位V）
  uint8_t frame_current;  // 壳架电流（0x190D低字节，单位A）
  uint16_t rated_current; // 额定电流（0x190E，单位A）
} Modbus_DeviceInfo;

// 4. 用户参数结构体（对应0x3000~0x3009、0x3016~0x301E、0x302E~0x3036）
typedef struct
{
  // 0x3000~0x3009
  uint16_t control_cmd;        // 控制命令（0x3000：0x00AA=合闸,0x0033=分闸等）
  uint16_t over_volt_en;       // 过压保护使能（0x3001：0x00AA=报警+跳闸等）
  uint16_t over_volt_thr;      // 过压保护阈值（0x3002，单位V，50~80，默认58）
  uint16_t over_current_mode;  // 过流保护模式（0x3003：0x00AA=定时限等）
  uint16_t over_current_thr;   // 过流保护阈值（0x3004，单位A，3~壳架电流）
  uint16_t over_volt_delay;    // 过压保护延时（0x3005，单位100ms，默认30=3s）
  uint16_t over_current_delay; // 过流定时限延时（0x3006，单位100ms，默认600=60s）
  uint16_t under_volt_en;      // 欠压保护使能（0x3007：同过压使能）
  uint16_t under_volt_thr;     // 欠压保护阈值（0x3008，单位V，35~47，默认43）
  uint16_t under_volt_delay;   // 欠压保护延时（0x3009，单位100ms，默认30=3s）

  // 0x3016~0x301E
  uint16_t port_ot_en;     // 端口过温保护使能（0x3016：0x00AA=启用等）
  uint16_t port_ot_thr;    // 端口过温保护阈值（0x3017，单位℃，70~130，默认120）
  uint16_t port_ot_delay;  // 端口过温保护延时（0x3018，单位100ms，默认30=3s）
  uint16_t board_ot_en;    // 板载过温保护使能（0x301C：同端口过温使能）
  uint16_t board_ot_thr;   // 板载过温保护阈值（0x301D，单位℃，70~100，默认100）
  uint16_t board_ot_delay; // 板载过温保护延时（0x301E，单位100ms，默认30=3s）

  // 0x302E~0x3036
  uint16_t over_volt_recover_en;       // 过压自恢复使能（0x302E：0x00AA=启用）
  uint16_t under_volt_recover_en;      // 欠压自恢复使能（0x302F：同过压自恢复）
  uint16_t volt_recover_hyst;          // 电压恢复回差值（0x3030，单位V，1~10，默认2）
  uint16_t over_current_reclose_en;    // 过流自动重合使能（0x3031：0x00AA=启用）
  uint16_t over_current_reclose_delay; // 过流重合延时（0x3032，单位100ms，默认600=60s）
  uint16_t over_current_reclose_cnt;   // 过流重合次数（0x3033，1~5，默认3）
  uint16_t over_current_alarm_thr;     // 过流报警阈值（0x3034，单位A，3~壳架电流）
  uint16_t user_code;                  // 用户代码（0x3035，默认1）
  uint16_t air_switch_alarm_mode;      // 空开断开告警方式（0x3036：0x00AA=按负载判断）
} Modbus_UserParam;

// 总数据结构体（整合所有模块）
typedef struct
{
  Modbus_CommParam comm_param;
  Modbus_RunStatus run_status;
  Modbus_DeviceInfo dev_info;
  Modbus_UserParam user_param;
} Modbus_AllData;
extern Modbus_AllData *swap_all_data;
#pragma pack(0)
static uint16_t modbus_get_uint16(const uint8_t *data_buf, uint16_t offset);

// 2. 从数据段提取32位有符号整数（大端，双寄存器）
static int32_t modbus_get_int32(const uint8_t *data_buf, uint16_t offset);

// 3. 从数据段提取32位无符号整数（大端，双寄存器）
static uint32_t modbus_get_uint32(const uint8_t *data_buf, uint16_t offset);

// 4. 波特率映射（文档0x1800低字节定义）
static uint32_t modbus_map_baud(uint8_t baud_code);

// 5. 校验位映射（文档0x1801高字节定义，返回字符串便于打印）
static const char *modbus_map_parity(uint8_t parity_code);
// 6. 停止位映射（文档0x1801低字节定义）
static const char *modbus_map_stop_bit(uint8_t stop_code);

/**
 * @brief 解析0x1800~0x181B寄存器（通讯参数+部分运行状态）
 * @param resp_buf：完整应答帧
 * @param resp_len：应答帧长度
 * @param all_data：总数据结构体（输出参数）
 * @return 0=成功，-1=帧错误，-2=数据长度不匹配
 */
int modbus_parse_1800_181B(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);
int modbus_parse_1824_1828(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);

int modbus_parse_18A4_18B5(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);
int modbus_parse_1900_190E(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);
int modbus_parse_3000_3009(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);
int modbus_parse_3016_301E(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);
int modbus_parse_302E_3036(const uint8_t *resp_buf, uint16_t resp_len, Modbus_AllData *all_data);
#endif // !_UINT_STATUS_C0MMON_H_
